#pragma once
#include<string>
#include<jsoncpp/json/json.h>
#include<memory>
#include<sstream>

#include"log.hpp"

enum calerror{
    DIV_ZERO_ERROR=1,
    OPER_ERROR
};

const std::string SEP="\r\n";
bool encode(std::string& message){//传进来的，必须是序列化后的字符串
    if(message.empty()){
        return false;
    }
    std::string package=std::to_string(message.size())+SEP+message+SEP;
    message=package;
    return true;
}

//len\r\n[message]\r\n
bool decode(std::string& package,std::string* message){//对报文进行解码
    auto pos=package.find(SEP);
    if(pos==std::string::npos){
        return false;
    }
    std::string message_length=package.substr(0,pos);
    size_t len=std::stoi(message_length);
    int full_len=message_length.size()+2*SEP.size()+len;
    if(package.size()<full_len){  //报文字数不够，并非完整报文
        return false;
    }

    *message=package.substr(pos+SEP.size(),len);
    package.erase(0,full_len);
    return true;
}

class request   //请求
{
public:
    request():_x(0),_y(0),_oper(0)
    {}
    request(int x,int y,char oper):_x(x),_y(y),_oper(oper)
    {}
    ~request()=default;
    bool Serialize(std::string& out_string){//将request的序列化结果，发送到out_string中
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["oper"]=_oper;

        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root,&ss); //将序列化的结果，发送到字符流中
        out_string=ss.str();//将ss流中的数据以string的形式输出给out_string

        return true;
    }
    bool deSerialize(std::string& in_string)//将in_string的字符，反序列化到request当中
    {
        Json::Value root;
        Json::Reader jsreader;  //Json::Reader是专门用来反序列化Json串的
        bool prasesuccessful=jsreader.parse(in_string,root); //将in_string的数据，反序列化到root当中

        if(!prasesuccessful){   //反序列化错误
            LOG(ERROR)<<"prase fail"<<jsreader.getFormatedErrorMessages();
            return false;
        }

        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _oper=root["oper"].asInt();
        return true;
    }
    int & X(){return _x;}
    int & Y(){return _y;}
    char & OPER(){return _oper;}
private:
    int _x;     //左操作数
    int _y;     //右操作数
    char _oper; //符号
};

class respond   //响应
{
public:
    respond():_ans(0),_code(0)
    {}
    respond(int ans,int code):_ans(ans),_code(code)
    {}
    bool Serialize(std::string& out_string)
    {
        Json::Value root;
        root["ans"]=_ans;
        root["code"]=_code;
        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root,&ss);
        out_string=ss.str();
        return true;
    }
    bool DeSerialize(std::string &in_string)
    {
        Json::Value root;
        Json::Reader jsreader;
        bool parsesuccessful=jsreader.parse(in_string,root);
        if(!parsesuccessful){
            LOG(ERROR)<<"prase fail"<<jsreader.getFormatedErrorMessages();
            return false;
        }
        _ans=root["ans"].asInt();
        _code=root["code"].asInt();
        return true;
    }
    int& ANS(){return _ans;}
    int& CODE(){return _code;}
    void display()
    {
        std::cout<<"ans:"<<_ans<<'['<<_code<<']'<<std::endl;
    }
private:
    int _ans;   //答案
    int _code;  //错误码
};